package pro.cherish.knowledgesqltool.core.common;

import net.sf.jsqlparser.expression.BinaryExpression;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.Parenthesis;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
import net.sf.jsqlparser.expression.operators.relational.*;
import net.sf.jsqlparser.statement.select.*;
import net.sf.jsqlparser.util.deparser.ExpressionDeParser;

import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * @author 创建人：cherish
 * @version 版本号：V1.0
 * <p>
 * ***************************修订记录************************************
 * 2019-08-31 cherish 创建该类功能。
 * **********************************************************************
 * </p>
 * @ClassName 类名：MyWhereExpressionDeParser
 * @Description 功能说明：
 * <p>
 * TODO
 * </p>
 * **********************************************************************
 * @date 创建日期： 2019-08-31 cherish
 */
public class MyWhereExpressionDeParser extends ExpressionDeParser {

    List<Expression> whereExpressionList;
    private Map<String, Object> userParamMap;
    private List<ChangeExpression> changeExpressionList;

    public MyWhereExpressionDeParser(SelectVisitor selectVisitor, StringBuilder buffer) {
        super(selectVisitor, buffer);
    }

    public MyWhereExpressionDeParser(SelectVisitor selectVisitor, StringBuilder builder, List<ChangeExpression> changeExpressionList, List<Expression> whereExpressionList, Map<String, Object> userParamMap) {
        super(selectVisitor, builder);
        this.whereExpressionList = whereExpressionList;
        this.changeExpressionList = changeExpressionList;
        this.userParamMap = userParamMap;
    }

    public void changeBinaryExpression(BinaryExpression expression) {
        Expression rightExpression = expression.getRightExpression();
        if (rightExpression instanceof SubSelect) {
            SelectBody selectBody = ((SubSelect) rightExpression).getSelectBody();
            if (selectBody instanceof PlainSelect) {
                CommonUtil.findWhereFragement(whereExpressionList, selectBody, changeExpressionList, userParamMap);
            } else if (selectBody instanceof SetOperationList) {
                List<SelectBody> selects = ((SetOperationList) selectBody).getSelects();
                for (SelectBody select : selects) {
                    if (select instanceof PlainSelect) {
                        CommonUtil.findWhereFragement(whereExpressionList, select, changeExpressionList, userParamMap);
                    }
                }
            }
        } else {
            List<String> paramList = CommonUtil.getParam(rightExpression.toString(), Pattern.compile(CommonConfig.getAllParamLabelParanStr()));
            if (paramList != null && paramList.size() != 0) {
                // 有配模板
                String key = paramList.get(0);
                Object value = userParamMap.get(key);
                if (value == null || "".equals(value)) {
                    changeExpressionList.add(new ChangeExpression(expression.toString(), CommonUtil.getOneEqOne().toString(), 0, 0));
                }
            }
        }
    }

    @Override
    public void visit(LikeExpression expression) {
        changeBinaryExpression(expression);
        super.visit(expression);
    }

    @Override
    public void visit(GreaterThan expression) {
        changeBinaryExpression(expression);
        super.visit(expression);
    }

    @Override
    public void visit(MinorThan expression) {
        changeBinaryExpression(expression);
        super.visit(expression);

    }
    @Override
    public void visit(ExistsExpression existsExpression){
        Expression rightExpression = existsExpression.getRightExpression();
        if(rightExpression instanceof SubSelect){
            PlainSelect selectBody = ((PlainSelect) ((SubSelect) rightExpression).getSelectBody());
            if(selectBody!=null){
                CommonUtil.findWhereFragement(whereExpressionList, selectBody,changeExpressionList,userParamMap);
            }
        }
    }
    @Override
    public void visit(EqualsTo expression) {
        changeBinaryExpression(expression);
        super.visit(expression);
    }

    @Override
    public void visit(GreaterThanEquals expression) {
        changeBinaryExpression(expression);
        super.visit(expression);
    }

    @Override
    public void visit(MinorThanEquals expression) {
        changeBinaryExpression(expression);
        super.visit(expression);
    }

    @Override
    public void visit(InExpression expression) {
        ItemsList rightItemsList = expression.getRightItemsList();
        if (rightItemsList != null && rightItemsList instanceof SubSelect) {
            SelectBody selectBody = ((SubSelect) rightItemsList).getSelectBody();
            if (selectBody != null) {
                if (selectBody instanceof PlainSelect) {
                    CommonUtil.findWhereFragement(whereExpressionList, (SelectBody) selectBody, changeExpressionList, userParamMap);
                } else if (selectBody instanceof SetOperationList) {
                    for (SelectBody select : ((SetOperationList) selectBody).getSelects()) {
                        CommonUtil.findWhereFragement(whereExpressionList, (SelectBody) selectBody, changeExpressionList, userParamMap);
                    }
                } else {
                    List<String> paramList = CommonUtil.getParam(expression.toString(), Pattern.compile(CommonConfig.getAllParamLabelParanStr()));
                    if (paramList != null && paramList.size() != 0) {
                        // 有配模板
                        String key = paramList.get(0);
                        Object o = userParamMap.get(key);
                        if (o != null) {
                            if (o instanceof Object[]) {
                                Object[] value = (Object[]) o;
                                if (value.length == 0) {
                                    changeExpressionList.add(new ChangeExpression(expression.toString(), CommonUtil.getOneEqOne().toString(), 0, 0));
                                }
                            } else if (o instanceof List) {
                                List<Object> value = (List<Object>) o;
                                if (value.size() == 0) {
                                    changeExpressionList.add(new ChangeExpression(expression.toString(), CommonUtil.getOneEqOne().toString(), 0, 0));
                                }
                            }
                        } else {
                            changeExpressionList.add(new ChangeExpression(expression.toString(), CommonUtil.getOneEqOne().toString(), 0, 0));
                        }
                    }
                }
            }
        } else if (rightItemsList != null && rightItemsList instanceof ExpressionList) {
            // 正常表达式 in()
            List<String> paramList = CommonUtil.getParam(expression.toString(), Pattern.compile(CommonConfig.getAllParamLabelParanStr()));
            if (paramList != null && paramList.size() != 0) {
                // 有配模板
                String key = paramList.get(0);
                Object o = userParamMap.get(key);
                if (o != null) {
                    if (o instanceof Object[]) {
                        Object[] value = (Object[]) o;
                        if (value.length == 0) {
                            changeExpressionList.add(new ChangeExpression(expression.toString(), CommonUtil.getOneEqOne().toString(), 0, 0));
                        }
                    } else if (o instanceof List) {
                        List<Object> value = (List<Object>) o;
                        if (value.size() == 0) {
                            changeExpressionList.add(new ChangeExpression(expression.toString(), CommonUtil.getOneEqOne().toString(), 0, 0));
                        }
                    }
                } else {
                    changeExpressionList.add(new ChangeExpression(expression.toString(), CommonUtil.getOneEqOne().toString(), 0, 0));
                }
            }
        }
        super.visit(expression);
    }

    @Override
    public void visit(OrExpression orExpression) {
        visitBinaryExpr(orExpression, "OR");
    }

    @Override
    public void visit(AndExpression andExpression) {
        visitBinaryExpr(andExpression, "AND");
    }


    private void visitBinaryExpr(BinaryExpression expr, String operator) {
        if (!(expr.getLeftExpression() instanceof OrExpression)
                && !(expr.getLeftExpression() instanceof AndExpression)
                && !(expr.getLeftExpression() instanceof Parenthesis)) {
        }
        expr.getLeftExpression().accept(this);
        // 添加操作符
        getBuffer().append(CommonUtil.addBlankSpace(operator));
        if (!(expr.getRightExpression() instanceof OrExpression)
                && !(expr.getRightExpression() instanceof AndExpression)
                && !(expr.getRightExpression() instanceof Parenthesis)) {
        }
        expr.getRightExpression().accept(this);
    }
}
